﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Threading;
using System.Collections.ObjectModel;
using SQLServerHealthCheck.Model;
using SQLServerOptimizer.PL.WPF;
using SQLServerHealthCheck.SQLServer;
using System.Data.SqlClient;
using System.ComponentModel;
using System.Threading;
using AG.Utilities;


namespace SQLServerOptimizer.PL.WPF
{
    public delegate void RunConnectionCheck(SQLServerInstance instance);

    public delegate void StatusUpdateEvent(SQLServerInstance Instance,bool result);
    public delegate void StatusCheckProccesCompleted();

    

    public class ConnectionCheckWorker : AsyncUtils.AsyncOperation
    {
        int countEventsCalls = 0;
        public event StatusUpdateEvent InstanceStatusResult;
        public event StatusCheckProccesCompleted StatusCheckProccessCompleted;
        private ObservableCollection<SQLServerInstance> sqlServerInstances;
        public ConnectionCheckWorker(DispatcherObject target, ObservableCollection<SQLServerInstance> SQLServerInstances)
            : base(target)
        {
            sqlServerInstances = SQLServerInstances;

        }

        public void Fail()
        {
            lock (this)
            {
                _fail = true;
            }
        }
        private bool _fail;

        protected override void DoWork()
        {
            _fail = false;

           try
           {
               foreach (SQLServerInstance sqlServerInstance in sqlServerInstances)
               {

                   if (!CancelRequested)
                   {
                       RunConnectionCheck runConnectionCheck = new RunConnectionCheck(IsSQLServerAccessible);
                       runConnectionCheck.BeginInvoke(sqlServerInstance, null, null);
                   }
                   if (_fail)
                   {
                       throw new Exception();
                   }
               }

            if (CancelRequested)
            {
                AcknowledgeCancel();
            }
           }
           catch (Exception ex)
           {
               Logger.Error(ex);
           }
          
           }
        public void IsSQLServerAccessible(SQLServerInstance sqlServerInstance)
        {
            bool result = CollectServerAndServiceData.IsSQLServerAccessible(sqlServerInstance.GetConnectionString("Master"));

            FireStatusUpdateEvent(sqlServerInstance,result);
            
        }

        private void FireStatusUpdateEvent(SQLServerInstance sqlServerInstance,bool result)
        {
            Object[] param = new Object[] { sqlServerInstance,result };

            FireAsync(InstanceStatusResult, param);
            countEventsCalls++;
            FireStatusProccessCompletedEvent();
            

        }

        private void FireStatusProccessCompletedEvent()
        {
            if (countEventsCalls == (sqlServerInstances.Count))
            {
                
                FireAsync(StatusCheckProccessCompleted);
                countEventsCalls = 0;
            }

        }
        }
   
   

    }


